{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ResnetTrick_create_model_fit\n",
    "\n",
    "> ResnetTrick_create_model_fit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# setup and imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# uncomment if you dont have this lib\n",
    "# pip install git+https://github.com/ayasyrev/model_constructor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# uncomment if you dont have this lib\n",
    "# pip install git+https://github.com/kornia/kornia"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from kornia.contrib import MaxBlurPool2d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from fastai.basic_train import *\n",
    "from fastai.vision import *\n",
    "from fastai.script import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import math\n",
    "import torch\n",
    "from torch.optim.optimizer import Optimizer, required\n",
    "import itertools as it"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We need model constructor for model and ConvLaer for new Resblock"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from model_constructor.net import *\n",
    "from model_constructor.layers import SimpleSelfAttention, ConvLayer"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# utils"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Mish activation function and Ranger otimizer, details here:  \n",
    "https://forums.fast.ai/t/meet-mish-new-activation-function-possible-successor-to-relu  \n",
    "https://forums.fast.ai/t/how-we-beat-the-5-epoch-imagewoof-leaderboard-score-some-new-techniques-to-consider  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Code was taken from   \n",
    "\n",
    "https://github.com/lessw2020/Ranger-Mish-ImageWoof-5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Mish(nn.Module):\n",
    "    def __init__(self):\n",
    "        super().__init__()\n",
    "#         print(\"Mish activation loaded...\")\n",
    "\n",
    "    def forward(self, x):  \n",
    "        #save 1 second per epoch with no x= x*() and then return x...just inline it.\n",
    "        return x *( torch.tanh(F.softplus(x))) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Ranger deep learning optimizer - RAdam + Lookahead combined.\n",
    "  #https://github.com/lessw2020/Ranger-Deep-Learning-Optimizer\n",
    "\n",
    "  #Ranger has now been used to capture 12 records on the FastAI leaderboard.\n",
    "\n",
    "  #This version = 9.3.19  \n",
    "\n",
    "  #Credits:\n",
    "  #RAdam -->  https://github.com/LiyuanLucasLiu/RAdam\n",
    "  #Lookahead --> rewritten by lessw2020, but big thanks to Github @LonePatient and @RWightman for ideas from their code.\n",
    "  #Lookahead paper --> MZhang,G Hinton  https://arxiv.org/abs/1907.08610\n",
    "\n",
    "  #summary of changes: \n",
    "  #full code integration with all updates at param level instead of group, moves slow weights into state dict (from generic weights), \n",
    "  #supports group learning rates (thanks @SHolderbach), fixes sporadic load from saved model issues.\n",
    "  #changes 8/31/19 - fix references to *self*.N_sma_threshold; \n",
    "                  #changed eps to 1e-5 as better default than 1e-8.\n",
    "\n",
    "class Ranger(Optimizer):\n",
    "\n",
    "    def __init__(self, params, lr=1e-3, alpha=0.5, k=6, N_sma_threshhold=5, betas=(.95,0.999), eps=1e-5, weight_decay=0):\n",
    "        #parameter checks\n",
    "        if not 0.0 <= alpha <= 1.0:\n",
    "            raise ValueError(f'Invalid slow update rate: {alpha}')\n",
    "        if not 1 <= k:\n",
    "            raise ValueError(f'Invalid lookahead steps: {k}')\n",
    "        if not lr > 0:\n",
    "            raise ValueError(f'Invalid Learning Rate: {lr}')\n",
    "        if not eps > 0:\n",
    "            raise ValueError(f'Invalid eps: {eps}')\n",
    "\n",
    "        #parameter comments:\n",
    "        # beta1 (momentum) of .95 seems to work better than .90...\n",
    "        #N_sma_threshold of 5 seems better in testing than 4.\n",
    "        #In both cases, worth testing on your dataset (.90 vs .95, 4 vs 5) to make sure which works best for you.\n",
    "\n",
    "        #prep defaults and init torch.optim base\n",
    "        defaults = dict(lr=lr, alpha=alpha, k=k, step_counter=0, betas=betas, N_sma_threshhold=N_sma_threshhold, eps=eps, weight_decay=weight_decay)\n",
    "        super().__init__(params,defaults)\n",
    "\n",
    "        #adjustable threshold\n",
    "        self.N_sma_threshhold = N_sma_threshhold\n",
    "\n",
    "        #now we can get to work...\n",
    "        #removed as we now use step from RAdam...no need for duplicate step counting\n",
    "        #for group in self.param_groups:\n",
    "        #    group[\"step_counter\"] = 0\n",
    "            #print(\"group step counter init\")\n",
    "\n",
    "        #look ahead params\n",
    "        self.alpha = alpha\n",
    "        self.k = k \n",
    "\n",
    "        #radam buffer for state\n",
    "        self.radam_buffer = [[None,None,None] for ind in range(10)]\n",
    "\n",
    "        #self.first_run_check=0\n",
    "\n",
    "        #lookahead weights\n",
    "        #9/2/19 - lookahead param tensors have been moved to state storage.  \n",
    "        #This should resolve issues with load/save where weights were left in GPU memory from first load, slowing down future runs.\n",
    "\n",
    "        #self.slow_weights = [[p.clone().detach() for p in group['params']]\n",
    "        #                     for group in self.param_groups]\n",
    "\n",
    "        #don't use grad for lookahead weights\n",
    "        #for w in it.chain(*self.slow_weights):\n",
    "        #    w.requires_grad = False\n",
    "\n",
    "    def __setstate__(self, state):\n",
    "        print(\"set state called\")\n",
    "        super(Ranger, self).__setstate__(state)\n",
    "\n",
    "\n",
    "    def step(self, closure=None):\n",
    "        loss = None\n",
    "        #note - below is commented out b/c I have other work that passes back the loss as a float, and thus not a callable closure.  \n",
    "        #Uncomment if you need to use the actual closure...\n",
    "\n",
    "        #if closure is not None:\n",
    "            #loss = closure()\n",
    "\n",
    "        #Evaluate averages and grad, update param tensors\n",
    "        for group in self.param_groups:\n",
    "\n",
    "            for p in group['params']:\n",
    "                if p.grad is None:\n",
    "                    continue\n",
    "                grad = p.grad.data.float()\n",
    "                if grad.is_sparse:\n",
    "                    raise RuntimeError('Ranger optimizer does not support sparse gradients')\n",
    "\n",
    "                p_data_fp32 = p.data.float()\n",
    "\n",
    "                state = self.state[p]  #get state dict for this param\n",
    "\n",
    "                if len(state) == 0:   #if first time to run...init dictionary with our desired entries\n",
    "                    #if self.first_run_check==0:\n",
    "                        #self.first_run_check=1\n",
    "                        #print(\"Initializing slow buffer...should not see this at load from saved model!\")\n",
    "                    state['step'] = 0\n",
    "                    state['exp_avg'] = torch.zeros_like(p_data_fp32)\n",
    "                    state['exp_avg_sq'] = torch.zeros_like(p_data_fp32)\n",
    "\n",
    "                    #look ahead weight storage now in state dict \n",
    "                    state['slow_buffer'] = torch.empty_like(p.data)\n",
    "                    state['slow_buffer'].copy_(p.data)\n",
    "\n",
    "                else:\n",
    "                    state['exp_avg'] = state['exp_avg'].type_as(p_data_fp32)\n",
    "                    state['exp_avg_sq'] = state['exp_avg_sq'].type_as(p_data_fp32)\n",
    "\n",
    "                #begin computations \n",
    "                exp_avg, exp_avg_sq = state['exp_avg'], state['exp_avg_sq']\n",
    "                beta1, beta2 = group['betas']\n",
    "\n",
    "                #compute variance mov avg\n",
    "                exp_avg_sq.mul_(beta2).addcmul_(1 - beta2, grad, grad)\n",
    "                #compute mean moving avg\n",
    "                exp_avg.mul_(beta1).add_(1 - beta1, grad)\n",
    "\n",
    "                state['step'] += 1\n",
    "\n",
    "\n",
    "                buffered = self.radam_buffer[int(state['step'] % 10)]\n",
    "                if state['step'] == buffered[0]:\n",
    "                    N_sma, step_size = buffered[1], buffered[2]\n",
    "                else:\n",
    "                    buffered[0] = state['step']\n",
    "                    beta2_t = beta2 ** state['step']\n",
    "                    N_sma_max = 2 / (1 - beta2) - 1\n",
    "                    N_sma = N_sma_max - 2 * state['step'] * beta2_t / (1 - beta2_t)\n",
    "                    buffered[1] = N_sma\n",
    "                    if N_sma > self.N_sma_threshhold:\n",
    "                        step_size = math.sqrt((1 - beta2_t) * (N_sma - 4) / (N_sma_max - 4) * (N_sma - 2) / N_sma * N_sma_max / (N_sma_max - 2)) / (1 - beta1 ** state['step'])\n",
    "                    else:\n",
    "                        step_size = 1.0 / (1 - beta1 ** state['step'])\n",
    "                    buffered[2] = step_size\n",
    "\n",
    "                if group['weight_decay'] != 0:\n",
    "                    p_data_fp32.add_(-group['weight_decay'] * group['lr'], p_data_fp32)\n",
    "\n",
    "                if N_sma > self.N_sma_threshhold:\n",
    "                    denom = exp_avg_sq.sqrt().add_(group['eps'])\n",
    "                    p_data_fp32.addcdiv_(-step_size * group['lr'], exp_avg, denom)\n",
    "                else:\n",
    "                    p_data_fp32.add_(-step_size * group['lr'], exp_avg)\n",
    "\n",
    "                p.data.copy_(p_data_fp32)\n",
    "\n",
    "                #integrated look ahead...\n",
    "                #we do it at the param level instead of group level\n",
    "                if state['step'] % group['k'] == 0:\n",
    "                    slow_p = state['slow_buffer'] #get access to slow param tensor\n",
    "                    slow_p.add_(self.alpha, p.data - slow_p)  #(fast weights - slow weights) * alpha\n",
    "                    p.data.copy_(slow_p)  #copy interpolated weights to RAdam param tensor\n",
    "\n",
    "        return loss"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Code for databanch and learner from fastai v1 examples."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_data(size=128, woof=1, bs=64, workers=None, **kwargs):\n",
    "    if woof:\n",
    "        path = URLs.IMAGEWOOF    # if woof \n",
    "    else:\n",
    "        path = URLs.IMAGENETTE\n",
    "    path = untar_data(path)\n",
    "    print('data path  ', path)\n",
    "    n_gpus = num_distrib() or 1\n",
    "    if workers is None: workers = min(8, num_cpus()//n_gpus)\n",
    "    return (ImageList.from_folder(path).split_by_folder(valid='val')\n",
    "            .label_from_folder().transform(([flip_lr(p=0.5)], []), size=size)\n",
    "            .databunch(bs=bs, num_workers=workers)\n",
    "            .presize(size, scale=(0.35,1))\n",
    "            .normalize(imagenet_stats))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_learn(\n",
    "        gpu:Param(\"GPU to run on\", str)=None,\n",
    "        woof: Param(\"Use imagewoof (otherwise imagenette)\", int)=1,\n",
    "        size: Param(\"Size (px: 128,192,224)\", int)=128,\n",
    "        alpha: Param(\"Alpha\", float)=0.99, \n",
    "        mom: Param(\"Momentum\", float)=0.95, #? 0.9\n",
    "        eps: Param(\"epsilon\", float)=1e-6,\n",
    "        bs: Param(\"Batch size\", int)=64,\n",
    "        mixup: Param(\"Mixup\", float)=0.,\n",
    "        opt: Param(\"Optimizer (adam,rms,sgd)\", str)='ranger',\n",
    "        sa: Param(\"Self-attention\", int)=0,\n",
    "        sym: Param(\"Symmetry for self-attention\", int)=0,\n",
    "        model: Param('model as partial', callable) = xresnet50\n",
    "        ):\n",
    " \n",
    "    if   opt=='adam' : opt_func = partial(optim.Adam, betas=(mom,alpha), eps=eps)\n",
    "    elif opt=='ranger'  : opt_func = partial(Ranger,  betas=(mom,alpha), eps=eps)\n",
    "    data = get_data(size, woof, bs)\n",
    "    learn = (Learner(data, model(), wd=1e-2, opt_func=opt_func,\n",
    "             metrics=[accuracy,top_k_accuracy],\n",
    "             bn_wd=False, true_wd=True,\n",
    "             loss_func = LabelSmoothingCrossEntropy(),))\n",
    "    print('Learn path', learn.path)\n",
    "    if mixup: learn = learn.mixup(alpha=mixup)\n",
    "    return learn"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ResBlock"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here is ResBlock with trick.  \n",
    "It only for models with expansion grater then 1.  \n",
    "\n",
    "If stride == 2, instead of create conv layer with kernel size (3*3) and stride 2, I just use conv layer with stride 1 (as default) and put pool layer befor convolutions. \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class NewResBlock(Module):\n",
    "    def __init__(self, expansion, ni, nh, stride=1, \n",
    "                 conv_layer=ConvLayer, act_fn=act_fn, bn_1st=True,\n",
    "                 pool=nn.AvgPool2d(2, ceil_mode=True), sa=False,sym=False, zero_bn=True):\n",
    "        nf,ni = nh*expansion,ni*expansion\n",
    "        self.reduce = noop if stride==1 else pool\n",
    "        layers  = [(f\"conv_0\", conv_layer(ni, nh, 3, stride=stride, act_fn=act_fn, bn_1st=bn_1st)),\n",
    "                   (f\"conv_1\", conv_layer(nh, nf, 3, zero_bn=zero_bn, act=False, bn_1st=bn_1st))\n",
    "        ] if expansion == 1 else [\n",
    "                   (f\"conv_0\",conv_layer(ni, nh, 1, act_fn=act_fn, bn_1st=bn_1st)),\n",
    "                   (f\"conv_1\",conv_layer(nh, nh, 3, stride=1, act_fn=act_fn, bn_1st=bn_1st)), #!!!\n",
    "                   (f\"conv_2\",conv_layer(nh, nf, 1, zero_bn=zero_bn, act=False, bn_1st=bn_1st))\n",
    "        ]\n",
    "        if sa: layers.append(('sa', SimpleSelfAttention(nf,ks=1,sym=sym)))\n",
    "        self.convs = nn.Sequential(OrderedDict(layers))\n",
    "        self.idconv = noop if ni==nf else conv_layer(ni, nf, 1, act=False)\n",
    "        self.merge =act_fn\n",
    "\n",
    "    def forward(self, x): \n",
    "        o = self.reduce(x)\n",
    "        return self.merge(self.convs(o) + self.idconv(o))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Model Constructor"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Lets create model constructor with xresnet50 settings."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = xresnet50(c_out=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we just change default ResBlock with New One."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.block = NewResBlock"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can check how it will be in model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "NewResBlock(\n",
       "  (reduce): AvgPool2d(kernel_size=2, stride=2, padding=0)\n",
       "  (convs): Sequential(\n",
       "    (conv_0): ConvLayer(\n",
       "      (conv): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "      (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "      (act_fn): ReLU(inplace=True)\n",
       "    )\n",
       "    (conv_1): ConvLayer(\n",
       "      (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "      (act_fn): ReLU(inplace=True)\n",
       "    )\n",
       "    (conv_2): ConvLayer(\n",
       "      (conv): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "      (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "    )\n",
       "  )\n",
       "  (idconv): ConvLayer(\n",
       "    (conv): Conv2d(256, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "    (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "  )\n",
       "  (merge): ReLU(inplace=True)\n",
       ")"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.body.l_1.bl_0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Lets chenge activation function, its easy!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.act_fn= Mish()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tricks from forum tread (and from code) to beat leaderboard."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.stem_sizes = [3,32,64,64]\n",
    "model.sa = True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "MaxBlurPool works extremly grate! \n",
    "\n",
    "https://github.com/ducha-aiki/Ranger-Mish-ImageWoof-5/blob/master/mxresnet.py#L121"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pool = MaxBlurPool2d(3, True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.pool = pool\n",
    "model.stem_pool = pool"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "So now we redy.  \n",
    "Lets explore model!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Look at model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can get model after call constructor, or you can just check some parts."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Sequential(\n",
       "  model xresnet50\n",
       "  (stem): Sequential(\n",
       "    (conv_0): ConvLayer(\n",
       "      (conv): Conv2d(3, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n",
       "      (bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "      (act_fn): Mish()\n",
       "    )\n",
       "    (conv_1): ConvLayer(\n",
       "      (conv): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "      (act_fn): Mish()\n",
       "    )\n",
       "    (conv_2): ConvLayer(\n",
       "      (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "      (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "      (act_fn): Mish()\n",
       "    )\n",
       "    (stem_pool): MaxBlurPool2d()\n",
       "  )\n",
       "  (body): Sequential(\n",
       "    (l_0): Sequential(\n",
       "      (bl_0): NewResBlock(\n",
       "        (convs): Sequential(\n",
       "          (conv_0): ConvLayer(\n",
       "            (conv): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_1): ConvLayer(\n",
       "            (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_2): ConvLayer(\n",
       "            (conv): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          )\n",
       "        )\n",
       "        (idconv): ConvLayer(\n",
       "          (conv): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "        (merge): Mish()\n",
       "      )\n",
       "      (bl_1): NewResBlock(\n",
       "        (convs): Sequential(\n",
       "          (conv_0): ConvLayer(\n",
       "            (conv): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_1): ConvLayer(\n",
       "            (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_2): ConvLayer(\n",
       "            (conv): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          )\n",
       "        )\n",
       "        (merge): Mish()\n",
       "      )\n",
       "      (bl_2): NewResBlock(\n",
       "        (convs): Sequential(\n",
       "          (conv_0): ConvLayer(\n",
       "            (conv): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_1): ConvLayer(\n",
       "            (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_2): ConvLayer(\n",
       "            (conv): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          )\n",
       "          (sa): SimpleSelfAttention(\n",
       "            (conv): Conv1d(256, 256, kernel_size=(1,), stride=(1,), bias=False)\n",
       "          )\n",
       "        )\n",
       "        (merge): Mish()\n",
       "      )\n",
       "    )\n",
       "    (l_1): Sequential(\n",
       "      (bl_0): NewResBlock(\n",
       "        (reduce): MaxBlurPool2d()\n",
       "        (convs): Sequential(\n",
       "          (conv_0): ConvLayer(\n",
       "            (conv): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_1): ConvLayer(\n",
       "            (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_2): ConvLayer(\n",
       "            (conv): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          )\n",
       "        )\n",
       "        (idconv): ConvLayer(\n",
       "          (conv): Conv2d(256, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "        (merge): Mish()\n",
       "      )\n",
       "      (bl_1): NewResBlock(\n",
       "        (convs): Sequential(\n",
       "          (conv_0): ConvLayer(\n",
       "            (conv): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_1): ConvLayer(\n",
       "            (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_2): ConvLayer(\n",
       "            (conv): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          )\n",
       "        )\n",
       "        (merge): Mish()\n",
       "      )\n",
       "      (bl_2): NewResBlock(\n",
       "        (convs): Sequential(\n",
       "          (conv_0): ConvLayer(\n",
       "            (conv): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_1): ConvLayer(\n",
       "            (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_2): ConvLayer(\n",
       "            (conv): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          )\n",
       "        )\n",
       "        (merge): Mish()\n",
       "      )\n",
       "      (bl_3): NewResBlock(\n",
       "        (convs): Sequential(\n",
       "          (conv_0): ConvLayer(\n",
       "            (conv): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_1): ConvLayer(\n",
       "            (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_2): ConvLayer(\n",
       "            (conv): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          )\n",
       "        )\n",
       "        (merge): Mish()\n",
       "      )\n",
       "    )\n",
       "    (l_2): Sequential(\n",
       "      (bl_0): NewResBlock(\n",
       "        (reduce): MaxBlurPool2d()\n",
       "        (convs): Sequential(\n",
       "          (conv_0): ConvLayer(\n",
       "            (conv): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_1): ConvLayer(\n",
       "            (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_2): ConvLayer(\n",
       "            (conv): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          )\n",
       "        )\n",
       "        (idconv): ConvLayer(\n",
       "          (conv): Conv2d(512, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "        (merge): Mish()\n",
       "      )\n",
       "      (bl_1): NewResBlock(\n",
       "        (convs): Sequential(\n",
       "          (conv_0): ConvLayer(\n",
       "            (conv): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_1): ConvLayer(\n",
       "            (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_2): ConvLayer(\n",
       "            (conv): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          )\n",
       "        )\n",
       "        (merge): Mish()\n",
       "      )\n",
       "      (bl_2): NewResBlock(\n",
       "        (convs): Sequential(\n",
       "          (conv_0): ConvLayer(\n",
       "            (conv): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_1): ConvLayer(\n",
       "            (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_2): ConvLayer(\n",
       "            (conv): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          )\n",
       "        )\n",
       "        (merge): Mish()\n",
       "      )\n",
       "      (bl_3): NewResBlock(\n",
       "        (convs): Sequential(\n",
       "          (conv_0): ConvLayer(\n",
       "            (conv): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_1): ConvLayer(\n",
       "            (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_2): ConvLayer(\n",
       "            (conv): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          )\n",
       "        )\n",
       "        (merge): Mish()\n",
       "      )\n",
       "      (bl_4): NewResBlock(\n",
       "        (convs): Sequential(\n",
       "          (conv_0): ConvLayer(\n",
       "            (conv): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_1): ConvLayer(\n",
       "            (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_2): ConvLayer(\n",
       "            (conv): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          )\n",
       "        )\n",
       "        (merge): Mish()\n",
       "      )\n",
       "      (bl_5): NewResBlock(\n",
       "        (convs): Sequential(\n",
       "          (conv_0): ConvLayer(\n",
       "            (conv): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_1): ConvLayer(\n",
       "            (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_2): ConvLayer(\n",
       "            (conv): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          )\n",
       "        )\n",
       "        (merge): Mish()\n",
       "      )\n",
       "    )\n",
       "    (l_3): Sequential(\n",
       "      (bl_0): NewResBlock(\n",
       "        (reduce): MaxBlurPool2d()\n",
       "        (convs): Sequential(\n",
       "          (conv_0): ConvLayer(\n",
       "            (conv): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_1): ConvLayer(\n",
       "            (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_2): ConvLayer(\n",
       "            (conv): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          )\n",
       "        )\n",
       "        (idconv): ConvLayer(\n",
       "          (conv): Conv2d(1024, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "        (merge): Mish()\n",
       "      )\n",
       "      (bl_1): NewResBlock(\n",
       "        (convs): Sequential(\n",
       "          (conv_0): ConvLayer(\n",
       "            (conv): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_1): ConvLayer(\n",
       "            (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_2): ConvLayer(\n",
       "            (conv): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          )\n",
       "        )\n",
       "        (merge): Mish()\n",
       "      )\n",
       "      (bl_2): NewResBlock(\n",
       "        (convs): Sequential(\n",
       "          (conv_0): ConvLayer(\n",
       "            (conv): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_1): ConvLayer(\n",
       "            (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "            (act_fn): Mish()\n",
       "          )\n",
       "          (conv_2): ConvLayer(\n",
       "            (conv): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "            (bn): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          )\n",
       "        )\n",
       "        (merge): Mish()\n",
       "      )\n",
       "    )\n",
       "  )\n",
       "  (head): Sequential(\n",
       "    (pool): AdaptiveAvgPool2d(output_size=1)\n",
       "    (flat): Flatten()\n",
       "    (fc): Linear(in_features=2048, out_features=10, bias=True)\n",
       "  )\n",
       ")"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Sequential(\n",
       "  (conv_0): ConvLayer(\n",
       "    (conv): Conv2d(3, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n",
       "    (bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "    (act_fn): Mish()\n",
       "  )\n",
       "  (conv_1): ConvLayer(\n",
       "    (conv): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "    (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "    (act_fn): Mish()\n",
       "  )\n",
       "  (conv_2): ConvLayer(\n",
       "    (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "    (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "    (act_fn): Mish()\n",
       "  )\n",
       "  (stem_pool): MaxBlurPool2d()\n",
       ")"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.stem"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Sequential(\n",
       "  (l_0): Sequential(\n",
       "    (bl_0): NewResBlock(\n",
       "      (convs): Sequential(\n",
       "        (conv_0): ConvLayer(\n",
       "          (conv): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_1): ConvLayer(\n",
       "          (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_2): ConvLayer(\n",
       "          (conv): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (idconv): ConvLayer(\n",
       "        (conv): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "      )\n",
       "      (merge): Mish()\n",
       "    )\n",
       "    (bl_1): NewResBlock(\n",
       "      (convs): Sequential(\n",
       "        (conv_0): ConvLayer(\n",
       "          (conv): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_1): ConvLayer(\n",
       "          (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_2): ConvLayer(\n",
       "          (conv): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (merge): Mish()\n",
       "    )\n",
       "    (bl_2): NewResBlock(\n",
       "      (convs): Sequential(\n",
       "        (conv_0): ConvLayer(\n",
       "          (conv): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_1): ConvLayer(\n",
       "          (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_2): ConvLayer(\n",
       "          (conv): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "        (sa): SimpleSelfAttention(\n",
       "          (conv): Conv1d(256, 256, kernel_size=(1,), stride=(1,), bias=False)\n",
       "        )\n",
       "      )\n",
       "      (merge): Mish()\n",
       "    )\n",
       "  )\n",
       "  (l_1): Sequential(\n",
       "    (bl_0): NewResBlock(\n",
       "      (reduce): MaxBlurPool2d()\n",
       "      (convs): Sequential(\n",
       "        (conv_0): ConvLayer(\n",
       "          (conv): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_1): ConvLayer(\n",
       "          (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_2): ConvLayer(\n",
       "          (conv): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (idconv): ConvLayer(\n",
       "        (conv): Conv2d(256, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "      )\n",
       "      (merge): Mish()\n",
       "    )\n",
       "    (bl_1): NewResBlock(\n",
       "      (convs): Sequential(\n",
       "        (conv_0): ConvLayer(\n",
       "          (conv): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_1): ConvLayer(\n",
       "          (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_2): ConvLayer(\n",
       "          (conv): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (merge): Mish()\n",
       "    )\n",
       "    (bl_2): NewResBlock(\n",
       "      (convs): Sequential(\n",
       "        (conv_0): ConvLayer(\n",
       "          (conv): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_1): ConvLayer(\n",
       "          (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_2): ConvLayer(\n",
       "          (conv): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (merge): Mish()\n",
       "    )\n",
       "    (bl_3): NewResBlock(\n",
       "      (convs): Sequential(\n",
       "        (conv_0): ConvLayer(\n",
       "          (conv): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_1): ConvLayer(\n",
       "          (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_2): ConvLayer(\n",
       "          (conv): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (merge): Mish()\n",
       "    )\n",
       "  )\n",
       "  (l_2): Sequential(\n",
       "    (bl_0): NewResBlock(\n",
       "      (reduce): MaxBlurPool2d()\n",
       "      (convs): Sequential(\n",
       "        (conv_0): ConvLayer(\n",
       "          (conv): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_1): ConvLayer(\n",
       "          (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_2): ConvLayer(\n",
       "          (conv): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (idconv): ConvLayer(\n",
       "        (conv): Conv2d(512, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (bn): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "      )\n",
       "      (merge): Mish()\n",
       "    )\n",
       "    (bl_1): NewResBlock(\n",
       "      (convs): Sequential(\n",
       "        (conv_0): ConvLayer(\n",
       "          (conv): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_1): ConvLayer(\n",
       "          (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_2): ConvLayer(\n",
       "          (conv): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (merge): Mish()\n",
       "    )\n",
       "    (bl_2): NewResBlock(\n",
       "      (convs): Sequential(\n",
       "        (conv_0): ConvLayer(\n",
       "          (conv): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_1): ConvLayer(\n",
       "          (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_2): ConvLayer(\n",
       "          (conv): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (merge): Mish()\n",
       "    )\n",
       "    (bl_3): NewResBlock(\n",
       "      (convs): Sequential(\n",
       "        (conv_0): ConvLayer(\n",
       "          (conv): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_1): ConvLayer(\n",
       "          (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_2): ConvLayer(\n",
       "          (conv): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (merge): Mish()\n",
       "    )\n",
       "    (bl_4): NewResBlock(\n",
       "      (convs): Sequential(\n",
       "        (conv_0): ConvLayer(\n",
       "          (conv): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_1): ConvLayer(\n",
       "          (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_2): ConvLayer(\n",
       "          (conv): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (merge): Mish()\n",
       "    )\n",
       "    (bl_5): NewResBlock(\n",
       "      (convs): Sequential(\n",
       "        (conv_0): ConvLayer(\n",
       "          (conv): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_1): ConvLayer(\n",
       "          (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_2): ConvLayer(\n",
       "          (conv): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (merge): Mish()\n",
       "    )\n",
       "  )\n",
       "  (l_3): Sequential(\n",
       "    (bl_0): NewResBlock(\n",
       "      (reduce): MaxBlurPool2d()\n",
       "      (convs): Sequential(\n",
       "        (conv_0): ConvLayer(\n",
       "          (conv): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_1): ConvLayer(\n",
       "          (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_2): ConvLayer(\n",
       "          (conv): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (idconv): ConvLayer(\n",
       "        (conv): Conv2d(1024, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "        (bn): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "      )\n",
       "      (merge): Mish()\n",
       "    )\n",
       "    (bl_1): NewResBlock(\n",
       "      (convs): Sequential(\n",
       "        (conv_0): ConvLayer(\n",
       "          (conv): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_1): ConvLayer(\n",
       "          (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_2): ConvLayer(\n",
       "          (conv): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (merge): Mish()\n",
       "    )\n",
       "    (bl_2): NewResBlock(\n",
       "      (convs): Sequential(\n",
       "        (conv_0): ConvLayer(\n",
       "          (conv): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_1): ConvLayer(\n",
       "          (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "          (act_fn): Mish()\n",
       "        )\n",
       "        (conv_2): ConvLayer(\n",
       "          (conv): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
       "          (bn): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "        )\n",
       "      )\n",
       "      (merge): Mish()\n",
       "    )\n",
       "  )\n",
       ")"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.body"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Sequential(\n",
       "  (pool): AdaptiveAvgPool2d(output_size=1)\n",
       "  (flat): Flatten()\n",
       "  (fc): Linear(in_features=2048, out_features=10, bias=True)\n",
       ")"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.head"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we ready to fit."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Learner"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can create Learner as usual in fastai v1, send model to Learner"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data path   /notebooks/data/imagewoof2\n"
     ]
    }
   ],
   "source": [
    "learn  = Learner(get_data(), model())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "But we got function get_learn (defined at begin of notebook)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Settings for learner."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "lr = 0.004\n",
    "epochs = 5\n",
    "moms = (0.95,0.95)\n",
    "start_pct = 0.72\n",
    "size=192\n",
    "bs=32"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Lr find"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data path   /notebooks/data/imagewoof2\n",
      "Learn path /notebooks/data/imagewoof2\n"
     ]
    }
   ],
   "source": [
    "learn = get_learn(model=model,size=size,bs=bs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "    <div>\n",
       "        <style>\n",
       "            /* Turns off some styling */\n",
       "            progress {\n",
       "                /* gets rid of default border in Firefox and Opera. */\n",
       "                border: none;\n",
       "                /* Needs to be in here for Safari polyfill so background images work as expected. */\n",
       "                background-size: auto;\n",
       "            }\n",
       "            .progress-bar-interrupted, .progress-bar-interrupted::-webkit-progress-bar {\n",
       "                background: #F44336;\n",
       "            }\n",
       "        </style>\n",
       "      <progress value='0' class='' max='1', style='width:300px; height:20px; vertical-align: middle;'></progress>\n",
       "      0.00% [0/1 00:00<00:00]\n",
       "    </div>\n",
       "    \n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: left;\">\n",
       "      <th>epoch</th>\n",
       "      <th>train_loss</th>\n",
       "      <th>valid_loss</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>top_k_accuracy</th>\n",
       "      <th>time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "  </tbody>\n",
       "</table><p>\n",
       "\n",
       "    <div>\n",
       "        <style>\n",
       "            /* Turns off some styling */\n",
       "            progress {\n",
       "                /* gets rid of default border in Firefox and Opera. */\n",
       "                border: none;\n",
       "                /* Needs to be in here for Safari polyfill so background images work as expected. */\n",
       "                background-size: auto;\n",
       "            }\n",
       "            .progress-bar-interrupted, .progress-bar-interrupted::-webkit-progress-bar {\n",
       "                background: #F44336;\n",
       "            }\n",
       "        </style>\n",
       "      <progress value='92' class='' max='282', style='width:300px; height:20px; vertical-align: middle;'></progress>\n",
       "      32.62% [92/282 00:28<00:58 8.8006]\n",
       "    </div>\n",
       "    "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "set state called\n",
      "LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.\n"
     ]
    }
   ],
   "source": [
    "learn.lr_find()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.recorder.plot()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# epochs 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data path   /notebooks/data/imagewoof2\n",
      "Learn path /notebooks/data/imagewoof2\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: left;\">\n",
       "      <th>epoch</th>\n",
       "      <th>train_loss</th>\n",
       "      <th>valid_loss</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>top_k_accuracy</th>\n",
       "      <th>time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>1.880600</td>\n",
       "      <td>1.861133</td>\n",
       "      <td>0.412064</td>\n",
       "      <td>0.889030</td>\n",
       "      <td>01:41</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>1.641007</td>\n",
       "      <td>1.565336</td>\n",
       "      <td>0.545686</td>\n",
       "      <td>0.931789</td>\n",
       "      <td>01:43</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>1.482279</td>\n",
       "      <td>1.355628</td>\n",
       "      <td>0.645202</td>\n",
       "      <td>0.946806</td>\n",
       "      <td>01:42</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>1.336290</td>\n",
       "      <td>1.240822</td>\n",
       "      <td>0.696615</td>\n",
       "      <td>0.956223</td>\n",
       "      <td>01:42</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>1.093125</td>\n",
       "      <td>1.069190</td>\n",
       "      <td>0.776533</td>\n",
       "      <td>0.974803</td>\n",
       "      <td>01:42</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn = get_learn(model=model,size=size,bs=bs)\n",
    "learn.fit_fc(epochs, lr, moms,start_pct)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data path   /notebooks/data/imagewoof2\n",
      "Learn path /notebooks/data/imagewoof2\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: left;\">\n",
       "      <th>epoch</th>\n",
       "      <th>train_loss</th>\n",
       "      <th>valid_loss</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>top_k_accuracy</th>\n",
       "      <th>time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>1.879902</td>\n",
       "      <td>1.819809</td>\n",
       "      <td>0.431407</td>\n",
       "      <td>0.885722</td>\n",
       "      <td>01:43</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>1.656415</td>\n",
       "      <td>1.542313</td>\n",
       "      <td>0.560448</td>\n",
       "      <td>0.933062</td>\n",
       "      <td>01:43</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>1.469006</td>\n",
       "      <td>1.351075</td>\n",
       "      <td>0.638839</td>\n",
       "      <td>0.949096</td>\n",
       "      <td>01:42</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>1.335581</td>\n",
       "      <td>1.270019</td>\n",
       "      <td>0.681598</td>\n",
       "      <td>0.959277</td>\n",
       "      <td>01:43</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>1.101048</td>\n",
       "      <td>1.067657</td>\n",
       "      <td>0.779588</td>\n",
       "      <td>0.975566</td>\n",
       "      <td>01:42</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn = get_learn(model=model,size=size,bs=bs)\n",
    "learn.fit_fc(epochs, lr, moms,start_pct)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data path   /notebooks/data/imagewoof2\n",
      "Learn path /notebooks/data/imagewoof2\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: left;\">\n",
       "      <th>epoch</th>\n",
       "      <th>train_loss</th>\n",
       "      <th>valid_loss</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>top_k_accuracy</th>\n",
       "      <th>time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>1.892767</td>\n",
       "      <td>1.742068</td>\n",
       "      <td>0.449733</td>\n",
       "      <td>0.891575</td>\n",
       "      <td>01:42</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>1.644838</td>\n",
       "      <td>1.503818</td>\n",
       "      <td>0.566556</td>\n",
       "      <td>0.934334</td>\n",
       "      <td>01:42</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>1.497712</td>\n",
       "      <td>1.357621</td>\n",
       "      <td>0.646220</td>\n",
       "      <td>0.946297</td>\n",
       "      <td>01:42</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>1.343219</td>\n",
       "      <td>1.217803</td>\n",
       "      <td>0.710868</td>\n",
       "      <td>0.961822</td>\n",
       "      <td>01:43</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>1.139646</td>\n",
       "      <td>1.077023</td>\n",
       "      <td>0.770171</td>\n",
       "      <td>0.974039</td>\n",
       "      <td>01:43</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn = get_learn(model=model,size=size,bs=bs)\n",
    "learn.fit_fc(epochs, lr, moms,start_pct)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data path   /notebooks/data/imagewoof2\n",
      "Learn path /notebooks/data/imagewoof2\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: left;\">\n",
       "      <th>epoch</th>\n",
       "      <th>train_loss</th>\n",
       "      <th>valid_loss</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>top_k_accuracy</th>\n",
       "      <th>time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>1.878127</td>\n",
       "      <td>1.790160</td>\n",
       "      <td>0.425299</td>\n",
       "      <td>0.900484</td>\n",
       "      <td>01:43</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>1.623020</td>\n",
       "      <td>1.506888</td>\n",
       "      <td>0.561212</td>\n",
       "      <td>0.934589</td>\n",
       "      <td>01:43</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>1.443853</td>\n",
       "      <td>1.382565</td>\n",
       "      <td>0.636040</td>\n",
       "      <td>0.943243</td>\n",
       "      <td>01:43</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>1.324397</td>\n",
       "      <td>1.262930</td>\n",
       "      <td>0.696360</td>\n",
       "      <td>0.957496</td>\n",
       "      <td>01:43</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>1.135156</td>\n",
       "      <td>1.050635</td>\n",
       "      <td>0.791041</td>\n",
       "      <td>0.977348</td>\n",
       "      <td>01:43</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn = get_learn(model=model,size=size,bs=bs)\n",
    "learn.fit_fc(epochs, lr, moms,start_pct)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data path   /notebooks/data/imagewoof2\n",
      "Learn path /notebooks/data/imagewoof2\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: left;\">\n",
       "      <th>epoch</th>\n",
       "      <th>train_loss</th>\n",
       "      <th>valid_loss</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>top_k_accuracy</th>\n",
       "      <th>time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>1.917708</td>\n",
       "      <td>1.784298</td>\n",
       "      <td>0.422245</td>\n",
       "      <td>0.890303</td>\n",
       "      <td>01:43</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>1.646729</td>\n",
       "      <td>1.526213</td>\n",
       "      <td>0.556121</td>\n",
       "      <td>0.934334</td>\n",
       "      <td>01:44</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>1.474678</td>\n",
       "      <td>1.394823</td>\n",
       "      <td>0.619242</td>\n",
       "      <td>0.948842</td>\n",
       "      <td>01:43</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>1.355496</td>\n",
       "      <td>1.235157</td>\n",
       "      <td>0.698906</td>\n",
       "      <td>0.963349</td>\n",
       "      <td>01:43</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>1.143730</td>\n",
       "      <td>1.066984</td>\n",
       "      <td>0.776279</td>\n",
       "      <td>0.975057</td>\n",
       "      <td>01:43</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn = get_learn(model=model,size=size,bs=bs)\n",
    "learn.fit_fc(epochs, lr, moms,start_pct)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.recorder.plot_losses()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x576 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.recorder.plot_metrics()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# e5 results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "acc = np.array([0.776533, 0.779588, 0.770171, 0.791041, 0.776279])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0.7787224, 0.00687586048724083)"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "acc.mean(), acc.std()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
